import requests
import json
import time
import cv2
import numpy as np
import random
import execjs
from pathlib import Path
from PIL import Image
def first():
    # 获取当前时间戳（毫秒级）
    timestamp = str(int(time.time() * 1000))

    url = "https://www.geetest.com/demo/gt/register-slide?t=" + timestamp
    headers = {
        "Authority": "www.qhrcg.com",
        "Method": "GET",
        "Path": "/demo/gt/register-slide?t=" + timestamp,
        "Scheme": "https",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "no-cache",
        "Pragma": "no-cache",
        "Referer": "https://www.geetest.com/demo/slide-float.html",
        "Sec-Ch-Ua": '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',
        "Sec-Ch-Ua-Mobile": "?1",
        "Sec-Ch-Ua-Platform": '"Android"',
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.82",
        "X-Requested-With": "XMLHttpRequest"
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        data = json.loads(response.text)
        gt=data["gt"]
        challenge = data["challenge"]
        return gt,challenge
    else:
        print("请求失败，状态码:", response.status_code)
def third(gt,challenge):
    timestamp = str(int(time.time() * 1000))
    url = "https://apiv6.geetest.com/get.php"
    params = {
        "gt": gt,
        "challenge": challenge,
        "lang": "zh-cn",
        "pt": "3",
        "client_type": "web_mobile",
        "w": "",
        "callback": "geetest_" + timestamp
    }
    headers = {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Host": "apiv6.geetest.com",
        "Pragma": "no-cache",
        "Referer": "https://www.geetest.com/demo/slide-float.html",
        "Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"",
        "Sec-Ch-Ua-Mobile": "?1",
        "Sec-Ch-Ua-Platform": "\"Android\"",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.82"
    }
    response = requests.get(url, params=params, headers=headers)
    response_text = response.text
    json_data = response_text.split('(', 1)[1].rsplit(')', 1)[0]
    data = json.loads(json_data)

def fourth(gt,challenge):
    timestamp = str(int(time.time() * 1000))
    url = "https://api.geevisit.com/ajax.php"
    params = {
        "gt": gt,
        "challenge": challenge,
        "lang": "zh-cn",
        "pt": "3",
        "client_type": "web_mobile",
        "w": "",
        "callback": "geetest_" + timestamp
    }

    headers = {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Host": "api.geetest.com",
        "Pragma": "no-cache",
        "Referer": "https://www.geetest.com/demo/slide-float.html",
        "Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"",
        "Sec-Ch-Ua-Mobile": "?1",
        "Sec-Ch-Ua-Platform": "\"Android\"",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.82"
    }
    response = requests.get(url, params=params, headers=headers)
def get_photo(gt,challenge):
    timestamp = str(int(time.time() * 1000))
    url = "https://api.geevisit.com/get.php"
    params = {
        "is_next": "true",
        "type": "slide3",
        "gt": gt,
        "challenge": challenge,
        "lang": "zh-cn",
        "https": "true",
        "protocol": "https://",
        "offline": "false",
        "product": "popup",
        "api_server": "api.geevisit.com",
        "isPC": "true",
        "autoReset": "true",
        "width": "100%",
        "callback": "geetest_" + timestamp
    }

    headers = {
        "Accept": "*/*",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Host": "api.geevisit.com",
        "Pragma": "no-cache",
        "Referer": "https://www.geetest.com/demo/slide-float.html",
        "Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"",
        "Sec-Ch-Ua-Mobile": "?1",
        "Sec-Ch-Ua-Platform": "\"Android\"",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.82"
    }
    response = requests.get(url, params=params, headers=headers)
    response_text = response.text
    json_data = response_text.split('(', 1)[1].rsplit(')', 1)[0]
    data = json.loads(json_data)
    return (data)
def save_image_from_url(url, filename):
    response = requests.get(url)
    if response.status_code == 200:
        with open(filename, 'wb') as f:
            f.write(response.content)
        #print(f"图片保存成功，保存路径为：{filename}")
    else:
        print("图片下载失败")
def parse_bg_captcha(img_path, im_show=False, save_path=None):
    _Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43,
           42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]
    w_sep, h_sep = 10, 80

    with Image.open(img_path) as img:
        img_cut_list = []
        for idx in range(len(_Ge)):
            x = _Ge[idx] % 26 * 12 + 1
            y = h_sep if _Ge[idx] > 25 else 0
            img_cut = img.crop((x, y, x + w_sep, y + h_sep))
            img_cut_list.append(img_cut)

        new_img = Image.new('RGB', (260, 160))
        for idx, img_cut in enumerate(img_cut_list):
            new_x = idx % 26 * 10
            new_y = h_sep if idx > 25 else 0
            new_img.paste(img_cut, (new_x, new_y))

    if im_show:
        new_img.show()
    if save_path:
        new_img.save(save_path)

    return new_img
def cv2_to_pil(img):
    # 将OpenCV图像转换为PIL图像
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    return Image.fromarray(img)
def pil_to_cv2(img):
    # 将PIL图像转换为OpenCV图像
    img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    return img
def get_distance(bg_img, tp_img, im_show=False, save_path=None):
    bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY)
    tp_gray = cv2.cvtColor(tp_img, cv2.COLOR_BGR2GRAY)
    tp_gray = cv2.Canny(tp_gray, 255, 255)
    bg_gray = cv2.Canny(bg_gray, 255, 255)
    result = cv2.matchTemplate(bg_gray, tp_gray, cv2.TM_CCOEFF_NORMED)
    _, _, _, max_loc = cv2.minMaxLoc(result)

    distance = max_loc[0]
    if save_path or im_show:
        tp_height, tp_width = tp_gray.shape[:2]
        x, y = max_loc
        _x, _y = x + tp_width, y + tp_height
        cv2.rectangle(bg_img, (x, y), (_x, _y), (0, 0, 255), 2)
        if save_path:
            save_path = Path(save_path).resolve()
            save_path = save_path.parent / f"{save_path.stem}.{distance}{save_path.suffix}"
            save_path = save_path.__str__()
            cv2.imwrite(save_path, cv2.cvtColor(bg_img, cv2.COLOR_RGB2BGR))
        if im_show:
            pil_image = cv2_to_pil(bg_img)
            pil_image.show()
    return distance
def last(gt,challenge,w):
    timestamp = str(int(time.time() * 1000))
    url = "https://api.geevisit.com/ajax.php"
    params = {
        'gt': gt,
        'challenge': challenge,
        'lang': 'zh-cn',
        "$_BCX": "3",
        'client_type': 'web_mobile',
        'w':w,
        "callback": "geetest_" + timestamp
    }

    headers = {
        "Accept": "*/*",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Host": "api.geevisit.com",
        "Pragma": "no-cache",
        "Referer": "https://www.geetest.com/demo/slide-float.html",
        "Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"",
        "Sec-Ch-Ua-Mobile": "?1",
        "Sec-Ch-Ua-Platform": "\"Android\"",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.82"
    }
    response = requests.get(url, params=params, headers=headers)
    response_text = response.text
    json_data = response_text.split('(', 1)[1].rsplit(')', 1)[0]
    data = json.loads(json_data)
    print(data)
    return(data)
success=0
def __ease_out_expo(sep):
    if sep == 1:
        return 1
    else:
        return 1 - pow(2, -10 * sep)
def get_slide_track(distance):
    """
    根据滑动距离生成滑动轨迹
    :param distance: 需要滑动的距离
    :return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
        x: 已滑动的横向距离
        y: 已滑动的纵向距离, 除起点外, 均为0
        t: 滑动过程消耗的时间, 单位: 毫秒
    """

    if not isinstance(distance, int) or distance < 0:
        raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
    # 初始化轨迹列表
    slide_track = [
        [random.randint(-50, -10), random.randint(-1, -1), 0],
        [0, 0, 0],
    ]
    # 共记录count次滑块位置信息
    count = 30 + int(distance / 2)
    # 初始化滑动时间
    t = random.randint(50, 100)
    # 记录上一次滑动的距离
    _x = 0
    _y = 0
    for i in range(count):
        # 已滑动的横向距离
        x = round(__ease_out_expo(i / count) * distance)
        # 滑动过程消耗的时间
        t += random.randint(10, 20)
        if x == _x:
            continue
        slide_track.append([x, random.randint(-1, 1), t])
        _x = x
    slide_track.append(slide_track[-1])
    return slide_track
for _ in range(1):
    # 记录开始时间
    gt,challenge = first()
    start_time = time.time()
    third(gt,challenge)
    fourth(gt,challenge)
    data = get_photo(gt,challenge)
    new_challenge = data['challenge']
    s = data['s']
    bg = "https://static.geetest.com/" + data['bg']
    slice = "https://static.geetest.com/" + data['slice']
    image_url = bg  # 替换为实际的图片地址
    filename = 'background.jpg'  # 保存的文件名，可以根据需要进行修改
    save_image_from_url(image_url, filename)
    image_url = slice  # 替换为实际的图片地址
    filename = 'slice.png'  # 保存的文件名，可以根据需要进行修改
    save_image_from_url(image_url, filename)
    parse_bg_captcha('background.jpg', im_show=False, save_path='bg.jpg')
    bg_img = cv2.imread('bg.jpg')
    tp_img = cv2.imread('slice.png')
    d = get_distance(
        bg_img=bg_img,
        tp_img=tp_img,
        im_show=False,
    )
    # 读取JS文件内容
    with open('jy.js', 'r', encoding="utf-8") as f:
        js_code = f.read()
    # 执行JS函数
    context = execjs.compile(js_code)
    result = context.call('get_w',gt, new_challenge, s,d)
    retval=last(gt,new_challenge, result)
    message = retval['message']
    if(message=="success"):
        success+=1
    end_time = time.time()
    # 记录结束时间
    # 计算代码执行时间（以毫秒为单位）
    execution_time = int((end_time - start_time) * 1000)
    print("识别所用时间：", execution_time, "毫秒")
print(f"成功次数：{success} 成功概率：{success/10*100}%")





